<?php declare(strict_types=1);

namespace App\Api\V2\Controller\Withhold\TL;

use App\Api\Controllers\BaseController;
use App\Services\Count\UserBillCountService;
use App\Services\PrintSqlService;
use App\Services\Withhold\TL\BillLogService;
use App\Traits\ResponseTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;

class BillController extends BaseController
{
    use ResponseTrait;

    /**
     * 账单列表
     * @return void
     */
    public function historyDataFile(Request $request): string
    {
        try {
            $data = $request->all();
            //LOCK
            $run = Redis::connection("default")->set($data["institution_number"] . $data["store_number"] . $data["transaction_date"], 1, ["ex" => 5, "nx"]);
            dd($run);
            if (!$run) {
                throw new \Exception("waiting");
            }
            dd(3212321);
            Log::channel("withhold")->info("通联代扣请求", $data);
//            {"institution_number":"0705","merchant_id":"202441784124453677","sign":"0dd6711df93dc1bd85f2f40f994e8301","transaction_date":"2025-03-19"}
            $validator = Validator::make($data, [
                "institution_number" => ["required"],
                "store_number" => ["required"],
                "sign" => ["required"],
                "transaction_date" => ["required"],
                "timestamp" => ["required"],
                "version" => ["required"]
            ], [], [
                "institution_number" => "机构号",
                "store_number" => "店铺编号",  //主店铺ID
                "sign" => "签名",
                "transaction_date" => "交易日期",
                "timestamp" => "时间戳",
                "version" => "2.0"
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            if ($data["version"] != "2.0") {
                throw new \Exception("请使用2.0版本");
            }

            //日期
            //校验
            if (strtotime($data["transaction_date"] . " 23:59:59") > strtotime(date("Y-m-d"))) {
                throw new \Exception("不能拉取今日的流水");
            }
            //签名校验
            $isSign = true;
            if (isset($data["check_sign"]) && $data["check_sign"] == "ignore_123") {
                $isSign = false;
                PrintSqlService::listen();
            }
            if ($isSign) {
                unset($data["check_sign"]);
                $isThrough = $this->checkSign($data);
                if ($isThrough == false) {
                    throw new \Exception("签名计算不通过");
                }
            }
            $where = [
                "institution_number" => $data["institution_number"],
                "store_number" => $data["store_number"],
                "sign" => $data["sign"],
                "transaction_date" => $data["transaction_date"],
            ];
            //获取账单数据
            $service = new BillLogService();
            $dataList = $service->billLogOneDay($where);
            //导入excel中
            $url = $service->makeExecl($dataList, $data["transaction_date"], $data["store_number"]);
            Log::channel("withhold")->info("通联代扣文件", ["url" => $url]);
            Db::table('mechanism_merchant_oss')->insert(['file_name' => $url]);
            return $this->successResponse("ok", [
                "url" => $url
            ]);
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage());
        }
    }


    protected function checkSign(array $data): bool
    {
        $allinpay_configs = Db::table('allinpay_configs')->where(['institution_number' => $data["institution_number"]])->first();
        $secret_key = isset($allinpay_configs->secret_key) ? $allinpay_configs->secret_key : ''; // key
        $sign = $data["sign"];
        unset($data["sign"]);
        ksort($data);
        $sb = "";
        foreach ($data as $k => $v) {
            $sb .= $k . "=" . $v . "&";
        }
        $sb .= "key=" . $secret_key;
        if ($sign == strtoupper(md5($sb))) {
            return true;
        }
        return false;
    }


}
